<!DOCTYPE html>
<html>
<head>
    <title>Oscillating Electric Dipole</title>
</head>
<body>
<canvas id="physicsCanvas" width="500" height="500"></canvas>
<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // Style parameters
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    // Coordinate and layout parameters
    const origin = { x: 250, y: 250 };
    const a = 90; // Distance from origin to charge
    const axisLength = 150;
    const arrowSize = 10;
    const chargeRadius = 4;
    const annotationOffsetX = -50;
    const tickLength = 12;
    
    /**
     * Helper function to draw an arrowhead at a point with a given angle.
     * @param {number} toX - The x-coordinate of the arrow tip.
     * @param {number} toY - The y-coordinate of the arrow tip.
     * @param {number} angle - The angle of the arrow direction in radians.
     */
    function drawArrowHead(toX, toY, angle) {
        ctx.save();
        ctx.beginPath();
        ctx.translate(toX, toY);
        ctx.rotate(angle);
        ctx.moveTo(0, 0);
        ctx.lineTo(-arrowSize, -arrowSize / 2.5);
        ctx.lineTo(-arrowSize, arrowSize / 2.5);
        ctx.closePath();
        ctx.fill();
        ctx.restore();
    }
    
    // --- Draw Axes ---
    // z-axis (vertical)
    ctx.beginPath();
    const z_bottom = origin.y + a + 30;
    const z_top = origin.y - axisLength;
    ctx.moveTo(origin.x, z_bottom);
    ctx.lineTo(origin.x, z_top);
    ctx.stroke();
    drawArrowHead(origin.x, z_top, -Math.PI / 2);
    ctx.font = 'italic 22px Times New Roman';
    ctx.fillText('z', origin.x + 20, z_top - 5);
    
    // y-axis (horizontal)
    const y_end = origin.x + axisLength;
    ctx.beginPath();
    ctx.moveTo(origin.x, origin.y);
    ctx.lineTo(y_end, origin.y);
    ctx.stroke();
    drawArrowHead(y_end, origin.y, 0);
    ctx.fillText('y', y_end + 20, origin.y);

    // x-axis (diagonal)
    const xAngle = -135 * Math.PI / 180; // Pointing bottom-left
    const x_end_x = origin.x + axisLength * Math.cos(xAngle);
    const x_end_y = origin.y - axisLength * Math.sin(xAngle);
    ctx.beginPath();
    ctx.moveTo(origin.x, origin.y);
    ctx.lineTo(x_end_x, x_end_y);
    ctx.stroke();
    drawArrowHead(x_end_x, x_end_y, xAngle);
    ctx.fillText('x', x_end_x - 15, x_end_y + 15);

    // --- Draw Charges and Labels ---
    const posQ = { x: origin.x, y: origin.y - a };
    const negQ = { x: origin.x, y: origin.y + a };

    // Draw charge points
    ctx.beginPath();
    ctx.arc(posQ.x, posQ.y, chargeRadius, 0, 2 * Math.PI);
    ctx.fill();

    ctx.beginPath();
    ctx.arc(negQ.x, negQ.y, chargeRadius, 0, 2 * Math.PI);
    ctx.fill();

    // Draw charge labels
    ctx.font = 'bold 22px Times New Roman';
    ctx.fillText('Q', posQ.x + 25, posQ.y + 5);
    ctx.fillText('-Q', negQ.x + 28, negQ.y + 5);

    // --- Draw Distance Annotations ---
    ctx.lineWidth = 1.5;
    
    // Top 'a'
    const annotationX = origin.x + annotationOffsetX;
    ctx.beginPath();
    ctx.moveTo(annotationX, origin.y);
    ctx.lineTo(annotationX, posQ.y);
    ctx.stroke();
    // Ticks for top 'a'
    ctx.beginPath();
    ctx.moveTo(annotationX - tickLength / 2, posQ.y);
    ctx.lineTo(annotationX + tickLength / 2, posQ.y);
    ctx.stroke();
    ctx.beginPath();
    ctx.moveTo(annotationX - tickLength / 2, origin.y);
    ctx.lineTo(annotationX + tickLength / 2, origin.y);
    ctx.stroke();
    
    // Bottom 'a'
    ctx.beginPath();
    ctx.moveTo(annotationX, origin.y);
    ctx.lineTo(annotationX, negQ.y);
    ctx.stroke();
    // Tick for bottom 'a'
    ctx.beginPath();
    ctx.moveTo(annotationX - tickLength / 2, negQ.y);
    ctx.lineTo(annotationX + tickLength / 2, negQ.y);
    ctx.stroke();

    // 'a' labels
    ctx.font = 'italic 22px Times New Roman';
    ctx.fillText('a', annotationX - 20, origin.y - a / 2);
    ctx.fillText('a', annotationX - 20, origin.y + a / 2);

    // --- Draw Figure Caption ---
    ctx.fillStyle = 'black';
    ctx.font = '20px Times New Roman';
    ctx.fillText('Fig. 4.28', origin.x, canvas.height - 30);

</script>
</body>
</html>